﻿using MathNet.Numerics.LinearAlgebra;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Graph.Algorithm.Core.Quant
{
    /// <summary>
    /// ======================
    /// </summary>
    public class Quant
    {

        public static Random randomBuilder { get; set; } = new Random();

        public VectorBuilder<Double> vectorBuilder { get; set; } = Vector<double>.Build;

        public Quant(double _alpha)
        {
            this.id = new int[] { 0, 0 };
            this.alpha = _alpha;
            this.beta = GetBeta();
        }

        public Quant()
        {
            this.id = new int[] { 0, 0 };
            this.alpha = 1d / Math.Sqrt(2);
            this.beta = 1d / Math.Sqrt(2);
        }

        public int Collapse()
        {
            var tag = randomBuilder.NextDouble();
            var res = Math.Pow(this.alpha, 2) < tag ? 0 : 1;
            collapsedValue = res;
            return res;
        }

        public double GetAlpha()
        {
            return Math.Sqrt(1 - this.beta * this.beta);
        }
        public double GetBeta()
        {
            return Math.Sqrt(1 - this.alpha * this.alpha);
        }

        public Vector<double> ToVector()
        {
            var vec = vectorBuilder.Dense(2);
            vec[0] = this.alpha;
            vec[1] = this.beta;
            return vec;
        }

        /// <summary>
        /// 量子旋转门
        /// </summary>
        public void Rotate()
        {
            var angle = this.theta * 0.01 * Math.PI;
            var a = this.alpha * Math.Cos(angle) - this.beta * Math.Sin(angle);
            var b = this.alpha * Math.Sin(angle) + this.beta * Math.Cos(angle);

            this.alpha = a;
            this.beta = b;
        }

        public int[] id { get; set; }
        public double alpha { get; set; }
        public double beta { get; set; }

        public int collapsedValue { get; set; }
        public double theta { get; set; }
    }

}
